Skip to content

reCAPTCHA v3 réglable sur les formulaires publics, et menus déroulants lisibles - #36

Merged
flocom merged 2 commits into
mainfrom
claude/remove-apel-sensitive-data-73l5iu
Aug 8, 2026
Merged

reCAPTCHA v3 réglable sur les formulaires publics, et menus déroulants lisibles#36
flocom merged 2 commits into
mainfrom
claude/remove-apel-sensitive-data-73l5iu

Conversation

@flocom

@flocom flocom commented Aug 8, 2026

Copy link
Copy Markdown
Owner

1. reCAPTCHA v3, réglable depuis Configuration

L'inscription bénévole et le formulaire de contact n'étaient protégés que par un champ piège : suffisant contre un robot naïf, inutile contre un envoi automatisé sérieux.

Configuration propose maintenant reCAPTCHA v3, désactivé par défaut : deux clés à coller depuis la console Google, et une exigence à choisir (souple 0,3 · équilibrée 0,5 · stricte 0,7).

  • La clé de site part dans la page, c'est sa nature ; la clé secrète est chiffrée en base et n'est jamais renvoyée au navigateur.
  • Elle est confirmée auprès de Google à l'enregistrement : une clé refusée bloque l'activation en le disant, plutôt que d'installer une protection qui ne protège rien.
  • Le jeton est vérifié côté serveur pour l'action attendue — un jeton obtenu sur un formulaire ne vaut pas pour l'autre.
  • Rien n'est chargé chez Google tant que c'est désactivé : le script n'est même pas demandé.
  • La politique de confidentialité gagne une section reCAPTCHA, affichée seulement quand il est actif.

Politique de refus, assumée

Situation Effet
Jeton absent envoi refusé, message mentionnant les bloqueurs de publicité
Note sous l'exigence envoi refusé
Jeton refusé par Google envoi refusé
Google injoignable envoi accepté, incident journalisé
Clé secrète refusée à l'usage envoi accepté, incident journalisé

Sur le site d'une association, empêcher un parent de s'inscrire parce qu'un service tiers est en panne coûte plus cher que de laisser passer un message indésirable.

Vérifié sur une instance réelle, API Google simulée : clé refusée à l'activation, clé acceptée, puis les cinq issues ci-dessus, et l'absence totale d'appel à Google une fois désactivé.

2. Les menus déroulants affichent les libellés longs

Un créneau nommé « Montage des barnums et installation des tables dans la cour de récréation — dimanche 23 août à 12h16 (6 places) » arrivait tronqué : un <select> natif ne sait revenir à la ligne, ni fermé ni ouvert.

Les navigateurs qui rendent la liste dans le document (appearance: base-select) se voient confier la mise en forme : libellé retenu sur plusieurs lignes dans le champ, options entières dans une liste bordée et ombrée, plus large que le champ si besoin. Ailleurs, rien ne change — le menu reste natif, avec le sélecteur du système sur mobile.

C'est une amélioration progressive plutôt qu'un menu maison, lequel aurait coûté la navigation au clavier, le rendu natif sur téléphone et la réécriture des vingt-neuf menus de l'application.

Vérifié dans Chromium 141 à 390 px : champ fermé passé de une à quatre lignes pour un libellé de 116 caractères, option de liste sur quatre lignes, et une seule flèche.

tsc --noEmit, npm run lint et next build passent.


Generated by Claude Code

claude added 2 commits August 8, 2026 10:13
L'inscription bénévole et le formulaire de contact n'étaient protégés que par
un champ piège : suffisant contre un robot naïf, inutile contre un envoi
automatisé un peu sérieux. Configuration propose maintenant reCAPTCHA v3,
désactivé par défaut.

Deux clés à coller depuis la console Google, et une exigence à choisir :
souple, équilibrée ou stricte. La clé de site part dans la page — c'est sa
nature — la clé secrète est chiffrée en base et n'est jamais renvoyée au
navigateur. Elle est confirmée auprès de Google à l'enregistrement : une clé
refusée bloque l'activation en le disant, plutôt que d'installer une
protection qui ne protège rien.

Le jeton est vérifié côté serveur, pour l'action attendue — un jeton obtenu
sur un formulaire ne vaut pas pour l'autre — et comparé à l'exigence retenue.

Deux refus de vérifier ne ferment pas le formulaire, par choix : si Google est
injoignable, ou si la clé secrète est refusée, l'envoi passe et l'incident est
journalisé. Sur le site d'une association, empêcher un parent de s'inscrire
parce qu'un service tiers est en panne coûte plus cher que de laisser passer un
message indésirable. Un jeton absent ou mal noté, en revanche, arrête l'envoi.

Rien n'est chargé chez Google tant que la protection n'est pas activée : le
script n'est même pas demandé. La politique de confidentialité gagne une
section sur reCAPTCHA, affichée seulement quand il est actif.

Vérifié sur une instance réelle : clé refusée à l'activation, clé acceptée,
puis les cinq issues d'un envoi — sans jeton, bien noté, mal noté, refusé,
Google injoignable — et l'absence totale d'appel à Google une fois la
protection désactivée.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014SfQYBU4xXTeSEHKhHQXdD
Un créneau nommé « Montage des barnums et installation des tables dans la cour
de récréation — dimanche 23 août à 12h16 (6 places) » arrivait tronqué : un
<select> natif ne sait revenir à la ligne ni dans le champ fermé, ni dans sa
liste.

Les navigateurs qui savent rendre cette liste dans le document — le select
personnalisable, `appearance: base-select` — se voient donc confier la mise en
forme : le libellé retenu passe à la ligne dans le champ, et chaque option
s'affiche en entier dans une liste bordée, ombrée, plus large que le champ si
besoin. Ailleurs, rien ne change : le menu reste celui du système, avec son
sélecteur natif sur mobile. C'est une amélioration progressive, pas le
remplacement du composant par un menu maison — lequel aurait coûté la
navigation au clavier, le rendu natif sur téléphone et une réécriture des
vingt-neuf menus de l'application.

Vérifié dans Chromium 141, en 390 px de large : champ fermé passé de une à
quatre lignes pour un libellé de 116 caractères, option de la liste rendue sur
quatre lignes également, et une seule flèche — la première version en affichait
deux, celle du navigateur et la nôtre.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014SfQYBU4xXTeSEHKhHQXdD
@flocom
flocom merged commit 719f343 into main Aug 8, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants